import type { VoiceRecognitionResult, SpeechRecognitionEvent } from '../types'

interface SpeechConfig {
  language?: string;
  continuous?: boolean;
  interimResults?: boolean;
  maxAlternatives?: number;
}

interface SpeechCallbacks {
  onResult?: (result: VoiceRecognitionResult) => void;
  onError?: (error: Error) => void;
  onStart?: () => void;
  onEnd?: () => void;
}

interface SpeechStatus {
  isSupported: boolean;
  isListening: boolean;
  hasRecognition: boolean;
}

interface SupportedLanguage {
  code: string;
  name: string;
}



/**
 * 语音识别服务
 */
class SpeechService {
  private recognition: any | null = null;
  private isSupported: boolean;
  private isListening: boolean = false;
  private callbacks: SpeechCallbacks = {
    onResult: undefined,
    onError: undefined,
    onStart: undefined,
    onEnd: undefined
  };

  private defaultConfig: SpeechConfig = {
    language: 'zh-CN',
    continuous: false,
    interimResults: true,
    maxAlternatives: 1
  };

  constructor() {
    this.isSupported = this.checkSupport()
  }

  // 公开只读属性，供外部判断浏览器支持
  get supported() {
    return this.isSupported;
  }

  /**
   * 检查浏览器支持
   */
  checkSupport(): boolean {
    return 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window
  }

  /**
   * 初始化语音识别
   */
  initialize(config: SpeechConfig = {}): any | null {
    if (!this.isSupported) {
      throw new Error('当前浏览器不支持语音识别')
    }

    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
    if (!SpeechRecognition) {
      throw new Error('语音识别API不可用')
    }

    this.recognition = new SpeechRecognition()

    const finalConfig = { ...this.defaultConfig, ...config }

    // 配置语音识别
    this.recognition.lang = finalConfig.language || 'zh-CN'
    this.recognition.continuous = finalConfig.continuous || false
    this.recognition.interimResults = finalConfig.interimResults || true
    this.recognition.maxAlternatives = finalConfig.maxAlternatives || 1

    // 绑定事件
    this.setupEventListeners()

    return this.recognition
  }

  /**
   * 设置事件监听器
   */
  private setupEventListeners(): void {
    if (!this.recognition) return

    // 开始识别
    this.recognition.onstart = () => {
      this.isListening = true
      console.log('语音识别开始')
      this.callbacks.onStart?.()
    }

    // 识别结果
    this.recognition.onresult = (event: SpeechRecognitionEvent) => {
      let interimTranscript = ''
      let finalTranscript = ''

      for (let i = event.resultIndex; i < event.results.length; i++) {
        const result = event.results[i]
        const transcript = result[0].transcript

        if (result.isFinal) {
          finalTranscript += transcript
        } else {
          interimTranscript += transcript
        }
      }

      const recognitionResult: VoiceRecognitionResult = {
        text: finalTranscript || interimTranscript,
        confidence: event.results[event.results.length - 1]?.[0]?.confidence || 0,
        isFinal: finalTranscript.length > 0,
        timestamp: Date.now()
      }

      this.callbacks.onResult?.(recognitionResult)
    }

    // 识别错误
    this.recognition.onerror = (event: any) => {
      console.error('语音识别错误:', event.error)
      this.isListening = false

      let errorMessage = '语音识别出错'
      switch (event.error) {
        case 'no-speech':
          errorMessage = '没有检测到语音'
          break
        case 'audio-capture':
          errorMessage = '无法捕获音频'
          break
        case 'not-allowed':
          errorMessage = '麦克风权限被拒绝'
          break
        case 'network':
          errorMessage = '网络错误'
          break
        case 'service-not-allowed':
          errorMessage = '语音识别服务不可用'
          break
        default:
          errorMessage = `语音识别错误: ${event.error}`
      }

      this.callbacks.onError?.(new Error(errorMessage))
    }

    // 识别结束
    this.recognition.onend = () => {
      this.isListening = false
      console.log('语音识别结束')
      this.callbacks.onEnd?.()
    }

    // 音频开始
    this.recognition.onaudiostart = () => {
      console.log('音频捕获开始')
    }

    // 音频结束
    this.recognition.onaudioend = () => {
      console.log('音频捕获结束')
    }

    // 语音开始
    this.recognition.onspeechstart = () => {
      console.log('检测到语音')
    }

    // 语音结束
    this.recognition.onspeechend = () => {
      console.log('语音结束')
    }

    // 声音开始
    this.recognition.onsoundstart = () => {
      console.log('检测到声音')
    }

    // 声音结束
    this.recognition.onsoundend = () => {
      console.log('声音结束')
    }
  }

  /**
   * 开始语音识别
   */
  start(callbacks: SpeechCallbacks = {}): void {
    if (!this.recognition) {
      throw new Error('语音识别未初始化')
    }

    if (this.isListening) {
      console.warn('语音识别已在进行中')
      return
    }

    // 设置回调函数
    this.callbacks = { ...this.callbacks, ...callbacks }

    try {
      this.recognition.start()
    } catch (error) {
      console.error('启动语音识别失败:', error)
      this.callbacks.onError?.(error as Error)
    }
  }

  /**
   * 停止语音识别
   */
  stop(): void {
    if (this.recognition && this.isListening) {
      this.recognition.stop()
    }
  }

  /**
   * 中止语音识别
   */
  abort(): void {
    if (this.recognition && this.isListening) {
      this.recognition.abort()
    }
  }

  /**
   * 更新配置
   */
  updateConfig(config: SpeechConfig): void {
    if (!this.recognition) return

    if (config.language) {
      this.recognition.lang = config.language
    }
    if (config.continuous !== undefined) {
      this.recognition.continuous = config.continuous
    }
    if (config.interimResults !== undefined) {
      this.recognition.interimResults = config.interimResults
    }
    if (config.maxAlternatives !== undefined) {
      this.recognition.maxAlternatives = config.maxAlternatives
    }
  }

  /**
   * 获取支持的语言列表
   */
  getSupportedLanguages(): SupportedLanguage[] {
    return [
      { code: 'zh-CN', name: '中文(简体)' },
      { code: 'zh-TW', name: '中文(繁体)' },
      { code: 'en-US', name: 'English (US)' },
      { code: 'en-GB', name: 'English (UK)' },
      { code: 'ja-JP', name: '日本語' },
      { code: 'ko-KR', name: '한국어' },
      { code: 'fr-FR', name: 'Français' },
      { code: 'de-DE', name: 'Deutsch' },
      { code: 'es-ES', name: 'Español' },
      { code: 'it-IT', name: 'Italiano' },
      { code: 'pt-BR', name: 'Português (Brasil)' },
      { code: 'ru-RU', name: 'Русский' },
      { code: 'ar-SA', name: 'العربية' },
      { code: 'hi-IN', name: 'हिन्दी' },
      { code: 'th-TH', name: 'ไทย' }
    ]
  }

  /**
   * 检查麦克风权限
   */
  async checkMicrophonePermission(): Promise<boolean> {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
      stream.getTracks().forEach(track => track.stop())
      return true
    } catch (error) {
      console.error('麦克风权限检查失败:', error)
      return false
    }
  }

  /**
   * 请求麦克风权限
   */
  async requestMicrophonePermission(): Promise<boolean> {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true
        }
      })
      stream.getTracks().forEach(track => track.stop())
      return true
    } catch (error) {
      console.error('请求麦克风权限失败:', error)
      throw new Error('无法获取麦克风权限')
    }
  }

  /**
   * 获取状态
   */
  getStatus(): SpeechStatus {
    return {
      isSupported: this.isSupported,
      isListening: this.isListening,
      hasRecognition: !!this.recognition
    }
  }

  /**
   * 销毁服务
   */
  destroy(): void {
    if (this.recognition) {
      this.stop()
      this.recognition = null
    }
    this.callbacks = {
      onResult: undefined,
      onError: undefined,
      onStart: undefined,
      onEnd: undefined
    }
  }
}

// 创建单例实例
const speechService = new SpeechService()

export default speechService
